#pragma once

#include <iostream>
#include <memory>
#include <sys/epoll.h>
#include "Socket.hpp"
#include "Log.hpp"
#include "Epoll.hpp"
// #include "nocopy.hpp"
uint32_t EVENT_IN = (EPOLLIN);
uint32_t EVENT_OUT = (EPOLLOUT);
const uint16_t defaultport=9998;
const int num=128;
class Epollserver
{
public:
    Epollserver(uint16_t port=defaultport)
    :port_(port)
    ,_listensock_ptr(new Sock())
    ,_epoll_ptr(new Epoll())
    {
    }
    void Init()
    {
        _listensock_ptr->Socket();
        _listensock_ptr->Bind(port_);
        _listensock_ptr->Listen();
        lg(Info,"create lestensock succes:%d",_listensock_ptr->Fd());
    }
    void Accepter()
    {
        string clientip;
        uint16_t port=defaultport;
        int sockfd=_listensock_ptr->Accept(clientip,port);
        if(sockfd>0)
        {
            _epoll_ptr->EpollCtl(EPOLL_CTL_ADD,sockfd,EVENT_IN);
        }
        
    }
    void Recver(int fd)//测试，是有bug的，读的不一定完整
    {
        char buffer[1024];
        ssize_t n=read(fd,buffer,sizeof(buffer));
        cout<<"收到的消息 "<<buffer<<endl;
        //
        string s="get message ";
        s+=buffer;
        write(fd,s.c_str(),s.size());
    }
    void Handler(struct epoll_event revents[num],int n)//派发
    {
        for(int i=0;i<n;i++)//一定是就绪的
        {
            uint32_t events=revents[i].events;
            int fd=revents[i].data.fd;
            if(events&EVENT_IN)
            {
                if(fd==_listensock_ptr->Fd())
                {
                    Accepter();
                }
                else
                {
                    Recver(fd);
                }
            }
        }
    }
    void start()//创建epoll.hpp
    {
        int n=_epoll_ptr->EpollCtl(EPOLL_CTL_ADD,_listensock_ptr->Fd(),EVENT_IN);
        struct epoll_event revents[num];
        while(true)
        {
            int n=_epoll_ptr->EpollWait(revents,num);
            if (n > 0)
            {  
                // 有事件就绪
                lg(Debug, "event happened, fd is : %d", revents[0].data.fd);
                Handler(revents,n);
            }
            else if (n == 0)
            {
                lg(Info, "time out ...");
            }
            else
            {
                lg(Error, "epll wait error");
            }
        }
    }
    ~Epollserver(){}
private:
    shared_ptr<Sock> _listensock_ptr;
    shared_ptr<Epoll> _epoll_ptr;
    uint16_t port_;
};